//-----------------------------------------------------------------------------
// Machinegun weapon. This file contains all the items related to this weapon
// including explosions, ammo, the item and the weapon item image.
// These objects rely on the item & inventory support system defined
// in item.cs and inventory.cs
//-----------------------------------------------------------------------------

//-----------------------------------------------------------------------------
// Weapon fire emitter

datablock AudioProfile(mac10ReloadSound)
{
	filename = "~/data/shapes/mac10/reload.wav";
	description = AudioClose3d;
	preload = true;
};

datablock AudioProfile(mac10FireSound)
{
	filename = "~/data/shapes/mac10/fire.wav";
	description = AudioClose3d;
	preload = true;
};

datablock AudioProfile(mac10ReloadSound)
{
	filename = "~/data/shapes/mac10/reload.wav";
	description = AudioClose3d;
	preload = true;
};

datablock AudioProfile(mac10FireEmptySound)
{
	filename = "~/data/shapes/mac10/noammo.wav";
	description = AudioClose3d;
	preload = true;
};

datablock AudioProfile(mac10ShellDropSound)
{
	filename = "~/data/shapes/mac10/shell_casing.ogg";
	description = AudioClose3d;
	preload = true;
};


datablock ParticleData(mac10FireParticle) 
{
	dragCoefficient = "0";
	windCoefficient = "0";
	gravityCoefficient = "-2";
	inheritedVelFactor = "0";
	constantAcceleration = "0";
	lifetimeMS = "200";
	lifetimeVarianceMS = "0";
	spinSpeed = "0";
	spinRandomMin = "-30";
	spinRandomMax = "0.5";
	useInvAlpha = "0";
	animateTexture = "0";
	framesPerSec = "1";
	textureName = "~/data/shapes/particles/smoke";
	animTexName[0] = "~/data/shapes/particles/smoke";
	colors[0] = "0.0 0.0 0.0 1.000000";
	colors[1] = "1.000000 1.000000 1.000000 0.096063";
	colors[2] = "0.000000 0.000000 0.000000 0.000000";
	colors[3] = "1.000000 1.000000 1.000000 1.000000";
	sizes[0] = "0.1";
	sizes[1] = "0.1";
	sizes[2] = "0.2";
	sizes[3] = "0.1";
	times[0] = "0";
	times[1] = "0.3";
	times[2] = "1";
	times[3] = "1";
	sgAllowLighting = "0";
};

datablock ParticleEmitterData(mac10FireEmitter) 
{
	className = "ParticleEmitterData";
	ejectionPeriodMS = "8";
	periodVarianceMS = "0";
	ejectionVelocity = "1";
	velocityVariance = "0";
	ejectionOffset = "0";
	thetaMin = "0";
	thetaMax = "50.4";
	phiReferenceVel = "0";
	phiVariance = "360";
	overrideAdvance = "0";
	orientParticles = "0";
	orientOnVelocity = "1";
	particles = "mac10FireParticle";
	lifetimeMS = "240";
	lifetimeVarianceMS = "0";
	useEmitterSizes = "0";
	useEmitterColors = "0";
};

//-----------------------------------------------------------------------------
// Projectile Explosion

datablock ParticleData(mac10ExplosionSmoke)
{
	textureName          = "~/data/shapes/particles/smoke";
	dragCoeffiecient     = 100.0;
	gravityCoefficient   = -4.5;
	inheritedVelFactor   = 0.25;
	constantAcceleration = -0.30;
	lifetimeMS           = 120;
	lifetimeVarianceMS   = 0;
	useInvAlpha =  true;
	spinRandomMin = -80.0;
	spinRandomMax =  80.0;

	colors[0]     = "1.0 1.0 1.0 0.1";
	colors[1]     = "1.0 1.0 1.0 0.1";
	colors[2]     = "1.0 1.0 1.0 0.2";

	sizes[0]      = 0.05;
	sizes[1]      = 0.05;
	sizes[2]      = 0.05;

	times[0]      = 0.0;
	times[1]      = 0.5;
	times[2]      = 1.0;
};

datablock ParticleEmitterData(mac10ExplosionSmokeEmitter)
{
	ejectionPeriodMS = 1;
	periodVarianceMS = 0;
	ejectionVelocity = 0.5;
	velocityVariance = 0.0;
	thetaMin         = 0.0;
	thetaMax         = 180.0;
	lifetimeMS       = 200;

	particles = "mac10ExplosionSmoke";
};

datablock ParticleData(mac10ExplosionFire)
{
	textureName          = "~/data/shapes/particles/fire";
	dragCoeffiecient     = 10.0;
	gravityCoefficient   = -0.0001;
	inheritedVelFactor   = 0.25;
	constantAcceleration = 0.1;
	lifetimeMS           = 200;
	lifetimeVarianceMS   = 10;
	useInvAlpha =  false;
	spinRandomMin = -80.0;
	spinRandomMax =  80.0;

	colors[0]     = "0.8 0.4 0 0.8";
	colors[1]     = "0.2 0.0 0 0.8";
	colors[2]     = "0.0 0.0 0.0 0.0";

	sizes[0]      = 0.05;
	sizes[1]      = 0.045;
	sizes[2]      = 0.005;

	times[0]      = 0.0;
	times[1]      = 0.5;
	times[2]      = 1.0;
};

datablock ParticleEmitterData(mac10ExplosionFireEmitter)
{
	ejectionPeriodMS = 10;
	periodVarianceMS = 0;
	ejectionVelocity = 0.5;
	velocityVariance = 0.5;
	thetaMin         = 0.0;
	thetaMax         = 180.0;
	lifetimeMS       = 150;
	particles = "mac10ExplosionFire";
};

datablock ExplosionData(mac10Explosion)
{
	lifeTimeMS = 900;

	// Volume particles
	particleDensity = 275;
	particleRadius = 0.02;

	particleEmitter = mac10ExplosionFireEmitter;

	// Point emission
	emitter[0] = mac10ExplosionSmokeEmitter;

	// Sub explosion objects

	// Camera Shaking
	shakeCamera = false;
	camShakeFreq = "10.0 11.0 10.0";
	camShakeAmp = "1.0 1.0 1.0";
	camShakeDuration = 0.5;
	camShakeRadius = 10.0;

	// Exploding debris
	debris = mac10ExplosionDebris;
	debrisThetaMin = 0;
	debrisThetaMax = 60;
	debrisPhiMin = 0;
	debrisPhiMax = 360;
	debrisNum = 6;
	debrisNumVariance = 2;
	debrisVelocity = 1;
	debrisVelocityVariance = 0.5;

	// Impulse
	impulseRadius = 10;
	impulseForce = 15;
};

//-----------------------------------------------------------------------------
// Projectile Object

datablock ProjectileData(mac10Projectile)
{
   projectileShapeName = "~/data/shapes/mac10/shell.dts";
   directDamage        = 5;
   radiusDamage        = 0;
   damageRadius        = 0.0;
   explosion           = mac10Explosion;

   //isShotGun = true;

   muzzleVelocity      = 815;
   velInheritFactor    = 1;

   armingDelay         = 0;
   lifetime            = 10000;
   fadeDelay           = 1300;
   bounceElasticity    = 0;
   bounceFriction      = 0;
   isBallistic         = false;
   gravityMod = 0.00;

   hasLight    = true;
   lightRadius = 2.0;
   lightColor = "0.8 0.8 0.4 1.0";

};

function mac10Projectile::onCollision(%this,%obj,%col,%fade,%pos,%normal)
{
	// Apply damage to the object all shape base objects
	if (%col.getType() & $TypeMasks::ShapeBaseObjectType)
		%col.damage(%obj,%pos,%this.directDamage,"mac10Bullet");

}


//-----------------------------------------------------------------------------
// Ammo Item

datablock ItemData(mac10Ammo)
{
	// Mission editor category
	category = "Ammo";

	// Add the Ammo namespace as a parent.  The ammo namespace provides
	// common ammo related functions and hooks into the inventory system.
	className = "Ammo";

	// Basic Item properties
	shapeFile = "~/data/shapes/mac10/ammo.dts";
	mass = 1;
	elasticity = 0.2;
	friction = 0.6;

	// Dynamic properties defined by the scripts
	pickUpName = "a mac10 magazine.";
	maxInventory = 30;
};

datablock ItemData(mac10AmmoClip)
{
	// Mission editor category
	category = "Ammo";

	// Add the Ammo namespace as a parent.  The ammo namespace provides
	// common ammo related functions and hooks into the inventory system.
	className = "Ammo";

	// Basic Item properties
	shapeFile = "~/data/shapes/mac10/ammo.dts";
	mass = 1;
	elasticity = 0.2;
	friction = 0.6;

	// Dynamic properties defined by the scripts
	pickUpName = "a mac10 magazine.";
	maxInventory = 1;
};


//--------------------------------------------------------------------------
// Machinegun shell that's ejected during reload.

datablock DebrisData(mac10Shell)
{
	shapeFile = "~/data/shapes/mac10/shell.dts";
	lifetime = 3.0;
	minSpinSpeed = 300.0;
	maxSpinSpeed = 400.0;
	elasticity = 0.5;
	friction = 0.2;
	numBounces = 4;
	staticOnMaxBounce = true;
	snapOnMaxBounce = false;
	fade = true;
};


//--------------------------------------------------------------------------
// Weapon Item.  This is the item that exists in the world, i.e. when it's
// been dropped, thrown or is acting as re-spawnable item.  When the weapon
// is mounted onto a shape, the MachinegunImage is used.

datablock ItemData(mac10)
{
	// Mission editor category
	category = "Weapon";

	// Hook into Item Weapon class hierarchy. The weapon namespace
	// provides common weapon handling functions in addition to hooks
	// into the inventory system.
	className = "Weapon";

	// Basic Item properties
	shapeFile = "~/data/shapes/mac10/weapon.dts";
	mass = 1;
	elasticity = 0.2;
	friction = 0.6;
	emap = true;

	// Dynamic properties defined by the scripts
	pickUpName = "a mac10 sub-machine gun";
	image = mac10Image;
};


//--------------------------------------------------------------------------
// Machinegun image which does all the work.  Images do not normally exist in
// the world, they can only be mounted on ShapeBase objects.

datablock ShapeBaseImageData(mac10Image)
{
	// Basic Item properties
	shapeFile = "~/data/shapes/mac10/weapon.dts";
	emap = true;

	// Specify mount point & offset for 3rd person, and eye offset
	// for first person rendering.
	mountPoint = 0;
	offset = "0 0 0";
	eyeOffset = "0.2 0.5 -0.4";

	//projectileSpread = 2/1000;

	// When firing from a point offset from the eye, muzzle correction
	// will adjust the muzzle vector to point to the eye LOS point.
	// Since this weapon doesn't actually fire from the muzzle point,
	// we need to turn this off.  
	correctMuzzleVector = false;

	// Add the WeaponImage namespace as a parent, WeaponImage namespace
	// provides some hooks into the inventory system.
	className = "WeaponImage";

	// Projectile && Ammo.
	item = mac10;
	ammo = mac10Ammo;
	clip = mac10AmmoClip;
	projectile = mac10Projectile;
	projectileType = Projectile;
	casing = mac10Shell;

	lightType = "WeaponFireLight" ;
	lightColor = "0.8 0.8 0.4 1.0" ;
	lightTime = "100" ;
	lightRadius = "2.5" ;   

	// Images have a state system which controls how the animations
	// are run, which sounds are played, script callbacks, etc. This
	// state system is downloaded to the client so that clients can
	// predict state changes and animate accordingly.  The following
	// system supports basic ready->fire->reload transitions as
	// well as a no-ammo->dryfire idle state.

	// Initial start up state
	stateName[0]                     = "Preactivate";
	stateTransitionOnLoaded[0]       = "Activate";
	stateTransitionOnNoAmmo[0]       = "NoAmmo";

	// Activating the gun.  Called when the weapon is first
	// mounted and there is ammo.
	//stateName[1]                     = "Activate";
	//stateTransitionOnTimeout[1]      = "Ready";
	//stateScript[1]                   = "setHud";
	//stateTimeoutValue[1]             = 0.34;
	//stateSequence[1]                 = "activate";
	//stateSound[1]                    = "mac10ActivateSound";
	stateName[1]                     = "Activate";
	stateTransitionOnTimeout[1]      = "Ready";
	stateTimeoutValue[1]             = 0.6;
	stateSequence[1]                 = "Activate";

	// Ready to fire, just waiting for the trigger
	stateName[2]                     = "Ready";
	stateTransitionOnNoAmmo[2]       = "NoAmmo";
	stateTransitionOnTriggerDown[2]  = "Fire";
	//stateScript[2]                   = "setHud";
	//stateSequence[2]                 = "Bob";

	// Fire the weapon. Calls the fire script which does 
	// the actual work.  Since we're a machinegun, skip the
	// reload animation...
	stateName[3]                     = "Fire";
	stateTransitionOnTimeout[3]      = "ReFire";
	stateTimeoutValue[3]             = 0.1;
	stateFire[3]                     = true;
	stateRecoil[3]                   = LightRecoil;
	stateAllowImageChange[3]         = true;
	stateSequence[3]                 = "Fire";
	stateScript[3]                   = "onFire";
	stateEmitter[3]                  = mac10FireEmitter;
	stateEmitterTime[3]              = 0.1;
	stateEjectShell[3]               = true;
	stateSound[3]                    = mac10FireSound;
	stateTransitionOnTriggerUp[3]    = "ShellDrop";

	// Reset the trigger by playing the activate sequence, then
	// if trigger is still down, loop back to firing.  This makes
	// the weapon fire continuously, like a machinegun
	stateName[4]                     = "ReFire";
	stateTransitionOnNoAmmo[4]       = "NoAmmo";
	stateTransitionOnTriggerDown[4]  = "Fire";
	//stateScript[4]                   = "setHud";
	stateTransitionOnTimeout[4]      = "Ready";
	stateTimeoutValue[4]             = 0.1;
	stateAllowImageChange[4]         = true;

	// No ammo in the weapon, just idle until something
	// shows up. Play the dry fire sound if the trigger is
	// pulled.
	stateName[5]                     = "NoAmmo";
	stateTransitionOnAmmo[5]         = "";
	//stateSequence[5]                 = "Bob";
	stateTransitionOnTriggerDown[5]  = "DryFire";

	// No ammo dry fire
	stateName[6]                     = "DryFire";
	stateTimeoutValue[6]             = 1.0;
	stateTransitionOnTimeout[6]      = "NoAmmo";
	stateSound[6]                    = mac10FireEmptySound;
	stateAllowImageChange[6]         = true;
	stateScript[6]                   = "AutoReload";

	stateName[7]                     = "ShellDrop";
	stateTimeoutValue[7]             = 0.0;
	stateTransitionOnTimeout[7]      = "Ready";

	stateName[8]                     = "Reload";
	stateTimeoutValue[8]             = 3.0;
	stateTransitionOnTimeout[8]      = "Ready";
	stateSound[8]                    = "mac10ReloadSound";
	stateSequence[8]                 = "Reload";
	stateAllowImageChange[8]         = false;
	stateScript[8]                   = "onReload";
};


//-----------------------------------------------------------------------------


function mac10Image::onFire(%this, %obj, %slot)
{
	%projectile = %this.projectile;

	// Decrement inventory ammo. The image's ammo state is update
	// automatically by the ammo inventory hooks.
	//%obj.decInventory(%this.ammo,1);
	//%currentAmmo = %obj.getInventory(%this.ammo);

	//%obj.client.setAmmoAmountHud(%currentAmmo);
	//%obj.client.SetWeaponNameHud("mac10 sub-machine gun");

	%projectile = %this.projectile;

	// Get the weapons projectile spread and ensure it is never 0
	//   (we need some spread direction even if it is extremely tiny)
	%spread = %this.projectileSpread;
	%spread = %spread $= "" ? 0.001 : %spread;
	%spread = %spread <= 0 ? 0.001 : %spread;

	// Determine if we are using a shotgun class weapon or not
	//   If we are using a shotgun, set the number of projectiles we are going to fire to 12

	%shellcount = 1;
	//if(%projectile.isShotGun)
	//     %shellcount = 12;


	// Create each projectile and send it on its way
	for(%shell=0; %shell<%shellcount; %shell++)
	{
		// Get the muzzle vector.  This is the dead straight aiming point of the gun
		%vector = %obj.getMuzzleVector(%slot);

		// Get our players velocity.  We must ensure that the players velocity is added
		//   onto the projectile
		%objectVelocity = %obj.getVelocity();

		// Determine scaled projectile vector.  This is still in a straight line as
		//   per the default example
		%vector1 = VectorScale(%vector, %projectile.muzzleVelocity);
		%vector2 = VectorScale(%objectVelocity, %projectile.velInheritFactor);
		%velocity = VectorAdd(%vector1,%vector2);

		// Determine our random x, y and z points in our spread circle and create
		//   a spread matrix.
		%x = (getRandom() - 0.5) * 2 * 3.1415926 * %spread;
		%y = (getRandom() - 0.5) * 2 * 3.1415926 * %spread;
		%z = (getRandom() - 0.5) * 2 * 3.1415926 * %spread;
		%mat = MatrixCreateFromEuler(%x @ " " @ %y @ " " @ %z);

		// Alter our projectile vector with our spread matrix
		%velocity = MatrixMulVector(%mat, %velocity);


		// Create our projectile
		%p = new (%this.projectileType)()
		{
			dataBlock        = %projectile;
			initialVelocity  = %velocity;
			initialPosition  = %obj.getMuzzlePoint(%slot);
			sourceObject     = %obj;
			sourceSlot       = %slot;
			client           = %obj.client;
		};
		MissionCleanup.add(%p);
		
	}

	schedule(400, 0, serverPlay3D, mac10ShellDropSound, %obj.client.player.getTransform());

	return %p;
}


function mac10Image::setHud(%this, %obj, %slot)
{ 
   //%obj.client.SetWeaponNameHud("mac10 sub-machine gun");

   //%currentAmmo = %obj.getInventory(%this.ammo);

   //%obj.client.SetAmmoAmountHud(%currentAmmo);

   //%ClipAmmo = %obj.getInventory(%this.clip);
   //%obj.client.setClipAmountHud(%ClipAmmo);
}

function mac10Image::AutoReload(%this, %obj)
{
	if (%obj.getInventory(%this.ammo) < 1)
	{
		commandToServer('WeaponReload');
	}
	else 
	{
	}
}

function mac10Image::onReload(%this, %obj, %slot)
{
	%ClipAmmo = %obj.getInventory(%this.clip);
	//%obj.client.setClipAmountHud(%ClipAmmo);
}

function mac10Image::ReloadAmmoClip(%this, %obj, %slot) 
{
	if (%obj.getInventory(%this.clip) > 0) 
	{
		%obj.manualSetImageState(%slot, Reload);

		%ClipAmmo = %obj.getInventory(%this.clip);
		//%obj.client.setClipAmountHud(%ClipAmmo);
		//remember to change this first number to the number of milliseconds 
		//that your animation lasts
		schedule(3000, 0, "reloadBullets",%this,%obj);
	} else {
		%ClipAmmo = %obj.getInventory(%this.clip);
		//%obj.client.setClipAmountHud(%ClipAmmo);
	}
}

function reloadBullets(%image, %obj) 
{
	// The ammo inventory state has changed, we need to update any
	// mounted images using this ammo to reflect the new state.
	for (%i = 0; %i < 8; %i++) {
		if (%image == %obj.getMountedImage(%i))
			%obj.setImageAmmo(%i,true);
	}

	//%obj.decInventory(%image.clip,1);
	//%obj.setInventory(%image.ammo,%image.ammo.maxInventory);
	%obj.setInventory(mac10Ammo, 30);

	%ClipAmmo = %obj.getInventory(%this.clip);
	//%obj.client.setClipAmountHud(%ClipAmmo);
}

function mac10AmmoClip::onInventory(%this, %obj, %amount)
{
	// The ammo inventory state has changed, we need to update any
	// mounted images using this ammo to reflect the new state.
	%ClipAmmo = %obj.getInventory(%this);
	//%obj.client.setClipAmountHud(%ClipAmmo);
}
